package com.xbongbong.sys.model.impl;

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.sys.domain.dao.RoleDao;
import com.xbongbong.sys.domain.entity.CoverRoleEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.model.CoverRoleModel;
import com.xbongbong.sys.model.RoleModel;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author kaka
 * @time 2018-8-24
 */
@Service("roleModel")
public class RoleModelImpl implements RoleModel {

    /**
     * 列表不会需要paas_permissions,permissions字段，该字段比较大
     */
    private static final String LIST_COLUMNS = "id,role_name,role_alias,data_permission, data_permission_detail, corpid,add_time,update_time,is_use,del";

    @Resource
    private RoleDao roleDao;
    @Resource
    private CoverRoleModel coverRoleModel;

    @Override
    public Integer insert(RoleEntity entity) {
        Integer now = DateUtil.getInt();
        entity.setAddTime(now);
        entity.setUpdateTime(now);
        return roleDao.insert(entity);
    }

    @Override
    public Integer update(RoleEntity entity) {
        Integer now = DateUtil.getInt();
        entity.setUpdateTime(now);
        return roleDao.update(entity);
    }

    @Override
    public RoleEntity getByKey(Integer id, String corpid) {
        RoleEntity role = roleDao.getByKey(id, corpid);
        // 若系统权限，再读一下权限覆盖表
        if (role.getCorpid().equals(PaasConstant.DEFAULT_DATA_CORPID)) {
            CoverRoleEntity coverRole = coverRoleModel.getByRoleId(role.getId(), corpid);
            if (coverRole != null) {
                role.setPermissions(coverRole.getPermissions());
                role.setPaasPermissions(coverRole.getPaasPermissions());
                role.setDataPermissionDetail(coverRole.getDataPermissionDetail());
                role.setDynamicPermissions(coverRole.getDynamicPermissions());
            }
        }
        return role;
    }

    @Override
    public List<RoleEntity> findEntitys(Map<String, Object> param) {
        /*
         * showPaasPermission 为特殊参数，为true时则为select * 为false时为正常过滤字段
         */
        Boolean showPaasPermission = param.get("showPaasPermission") == null ? false : (Boolean) param.get("showPaasPermission");
        if (!showPaasPermission) {
            param.put("columns", LIST_COLUMNS);
        }

        // 本公司公司id，不能放下面会被替换掉
        String corpid = (String) param.get("corpid");
        // 本公司权限
        List<RoleEntity> corpRoleList = roleDao.findEntitys(param);
        // 默认权限
        param.put("corpid", "0");
        List<RoleEntity> defaultRoleList = roleDao.findEntitys(param);
        // 系统角色能够编辑插入逻辑: 覆盖自定义系统权限到默认系统权限
        setCoverRole(defaultRoleList, corpid);

        // 取并集
        defaultRoleList.addAll(corpRoleList);

        return defaultRoleList;
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        //本公司角色数
        Integer countCorp = roleDao.getEntitysCount(param);
        //默认角色数
        param.put("corpid", "0");
        Integer countDefault = roleDao.getEntitysCount(param);
        // 求和
        return countCorp + countDefault;
    }

    @Override
    public List findEntitysWithoutSub(Map<String, Object> param) {
        return null;
    }

    @Override
    public Integer getCorpRoleCount(String corpid) {
        Map<String, Object> param = new HashMap<>(8);
        param.put("corpid", corpid);
        param.put("del", 0);
        return roleDao.getEntitysCount(param);
    }

    @Override
    public List<RoleEntity> getByRoleIdIn(String corpid, Collection<Integer> roleIdIn) {
        return getByRoleIdIn(corpid, roleIdIn, false);
    }

    @Override
    public List<RoleEntity> getByRoleIdIn(String corpid, Collection<Integer> roleIdIn, boolean showPaasPermission) {
        Map<String, Object> param = new HashMap<>(8);
        param.put("corpid", corpid);
        param.put("idIn", roleIdIn);
        param.put("showPaasPermission", showPaasPermission);
        param.put("del", 0);
        param.put("isUse", 1);
        return findEntitys(param);
    }

    @Override
    public Integer deleteByKey(Integer id, String corpid) {
        return roleDao.deleteByKey(id, corpid);
    }

    @Override
    public void updateBatch(List<RoleEntity> roleEntityList, String corpid) {
        roleDao.updateBatch(roleEntityList, corpid);
    }

    @Override
    public void updateBatchPermissions(List<RoleEntity> roleEntityList, String corpid) {
        roleDao.updateBatchPermissions(roleEntityList, corpid);
    }

    @Override
    public void updateRoleName(Integer id, String corpid, String roleName) {
        roleDao.updateRoleName(id, corpid, roleName);
    }

    @Override
    public List<RoleEntity> findAllRoleByCorpid(Map<String, Object> param) {
        return roleDao.findEntitys(param);
    }

    /**
     * 获取该表中的最大id，用于资金三期数据迁移
     *
     * @param param
     * @return
     */
    @Override
    public Long getMaxId(Map<String, Object> param) {
        return roleDao.getMaxId(param);
    }

    /**
     * 批量更新角色表，用于资金三期脚本迁移
     *
     * @param updateList
     */
    @Override
    public void updateBatchAll(List<RoleEntity> updateList) {
        roleDao.updateBatchAll(updateList);
    }

    @Override
    public void batchAppendPermissions(String appendRole, String existRole, List<String> corpidList) {
        roleDao.batchAppendPermissions(appendRole,existRole,corpidList);
    }

    /**
     * 系统权限支持自定义后需要覆盖自义定权限到系统权限实体
     * @param defaultRoleList 需要覆盖的系统权限列表
     * @param corpid 公司id
     */
    private void setCoverRole(List<RoleEntity> defaultRoleList, String corpid) {
        if (defaultRoleList == null || defaultRoleList.size() < 1 || StringUtil.isEmpty(corpid)) {
            return;
        }
        Set<Integer> defaultRoleIds = new HashSet<>();
        for (RoleEntity role : defaultRoleList) {
            defaultRoleIds.add(role.getId());
        }
        List<CoverRoleEntity> coverRoles = coverRoleModel.getByRoleIdIn(defaultRoleIds, corpid);
        if (coverRoles != null) {
            Map<Integer, CoverRoleEntity> coverRoleMap = new HashMap<>(16);
            for (CoverRoleEntity coverRole : coverRoles) {
                coverRoleMap.put(coverRole.getRoleId(), coverRole);
            }
            for (RoleEntity role : defaultRoleList) {
                CoverRoleEntity coverRole = coverRoleMap.get(role.getId());
                if (coverRole != null) {
                    role.setPaasPermissions(coverRole.getPaasPermissions());
                    role.setPermissions(coverRole.getPermissions());
                    role.setDynamicPermissions(coverRole.getDynamicPermissions());
                }
            }
        }
    }

}
